<script lang="ts" setup>
import type { AuthenticationInformationProps } from '@croco/framework/libraries';

import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';

import { AuthenticationLogin } from '@croco/framework/libraries';
import { $t } from '@croco/framework/locales';
import { preferences } from '@croco/framework/preferences';
import { useUserStore } from '@croco/framework/stores';

import { ElNotification } from 'element-plus';

import { getUserDetails } from '#/api';
import { service } from '#/api/request';
import VLoginForm from '#/bean/login-form.vue';

defineOptions({ name: 'Login' });

const userStore = useUserStore();

const router = useRouter();

const loading = ref(false);
const loginFormRef = ref();
const captchaImage = ref();
const form = ref<AuthenticationInformationProps>({
    uuid: undefined,
    username: '',
    password: '1234qwer',
    code: undefined,
    remember: false,
    grantType: 'password',
});
const rules = ref({
    username: [{ required: true, message: $t('authentication.usernameTip'), trigger: 'blur' }],
    password: [{ required: true, message: $t('authentication.passwordTip'), trigger: 'blur' }],
    code: [{ required: true, message: $t('authentication.codeTip'), trigger: 'blur' }],
});

const handleCaptcha = () => {
    form.value.uuid = `v${Math.random()}`;
    service
        .get(`/captcha?uuid=${form.value.uuid}`)
        .then(({ data }) => {
            captchaImage.value = data ? `data:image/gif;base64,${data}` : '';
        })
        .catch(() => {});
};

const handleSubmit = (remember: (username: string) => void) => {
    loginFormRef.value.validate(async (valid: boolean) => {
        if (valid) {
            loading.value = true;
            service
                .post('/login', form.value)
                .then(async ({ data }) => {
                    if (data.loginUser.token) {
                        remember(form.value.username);
                        userStore.setLoginUser(data.loginUser);

                        const { code, details, permissions } = await getUserDetails();
                        if (code === 200) {
                            userStore.setUserInfo(details);
                            userStore.setAccessPerms(permissions);
                        }

                        if (userStore.loginExpired) {
                            userStore.setLoginExpired(false);
                        } else {
                            await router.push(details.homePath || preferences.app.defaultHomePath);
                        }
                        ElNotification({
                            message: `${$t('authentication.loginSuccessDesc', [details.nickname, data.lastLoginTime ?? '--'])}`,
                            title: $t('authentication.loginSuccess'),
                            type: 'success',
                            position: 'bottom-right',
                        });
                    }
                })
                .catch(() => {
                    handleCaptcha();
                })
                .finally(() => {
                    loading.value = false;
                });
        }
    });
};

onMounted(() => handleCaptcha());
</script>

<template>
    <AuthenticationLogin v-model="form" :loading="loading" :submit="handleSubmit">
        <VLoginForm ref="loginFormRef" v-model="form" :rules="rules" :captcha-image="captchaImage" @captcha="handleCaptcha" />
    </AuthenticationLogin>
</template>
